import os
import re
import sys
import subprocess
import json
from datetime import datetime

from src.ui.i18n import _
from PySide6.QtWidgets import (
    QWidget, QVBoxLayout, QFormLayout, QHBoxLayout, QGroupBox,
    QPushButton, QFileDialog, QLineEdit, QComboBox,
    QMessageBox, QTableWidget, QTableWidgetItem, QHeaderView, QLabel, QCheckBox, QStyle,
    QSplitter, QMenu, QSizePolicy
)
from PySide6.QtCore import Qt, QTimer

from src.config import app_config
from src.translation.translation_worker import TranslationWorker
from src.utils.formatter import format_seconds
from src.utils.logger import get_logger, create_task_logger
from src.ui.widgets.translation_options_widget import TranslationOptionsWidget
from src.ui.dialogs.subtitle_editor_dialog import SubtitleEditorDialog


class TranslationTab(QWidget):
    def __init__(self, main_window=None, parent=None):
        super().__init__(parent)
        self.main_window = main_window
        self.worker = None
        self.history_file = "translation_history.json"
        self.history_data = []

        self._setup_ui()
        self._connect_signals()
        self._load_history()
        self.retranslate_ui()
        self.timer = QTimer(self)
        self.timer.timeout.connect(self._update_timer)
        app_config.config_saved.connect(self.reload_config)

    def reload_config(self):
        get_logger(__name__).debug("Reloading config and updating UI...")
        if hasattr(self, 'translation_options'):
            self.translation_options.reload_config()

    def _setup_ui(self):
        main_layout = QVBoxLayout(self)

        # --- Top Settings Panel ---
        settings_group = QGroupBox()
        settings_group.setObjectName("settings_group_box")
        settings_group.setTitle(_("Translation Settings"))
        # This group should be vertically fixed and horizontally expanding to fill the available space.
        settings_group.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
        
        # Use a QVBoxLayout to stack the SRT path and the options widget
        settings_group_layout = QVBoxLayout(settings_group)

        # A dedicated layout for the SRT file path selection
        srt_path_layout = QHBoxLayout()
        self.srt_path_label = QLabel()
        self.srt_path_edit = QLineEdit()
        self.srt_path_button = QPushButton()
        self.srt_path_button.setIcon(self.style().standardIcon(QStyle.StandardPixmap.SP_DirOpenIcon))

        srt_path_layout.addWidget(self.srt_path_label)
        srt_path_layout.addWidget(self.srt_path_edit)
        srt_path_layout.addWidget(self.srt_path_button)

        settings_group_layout.addLayout(srt_path_layout)

        # Add the separate, self-contained options widget
        self.translation_options = TranslationOptionsWidget(self)
        settings_group_layout.addWidget(self.translation_options)
        
        main_layout.addWidget(settings_group)

        # --- History Panel ---
        history_group = QGroupBox()
        history_group.setObjectName("history_group_box")
        history_group.setTitle(_("History"))
        # This group will expand to fill the available space by default
        history_group_layout = QVBoxLayout(history_group)
        
        self.history_table = QTableWidget()
        self.history_table.setColumnCount(5)
        self.history_table.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeMode.Stretch)
        self.history_table.setEditTriggers(QTableWidget.EditTrigger.NoEditTriggers)
        self.history_table.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
        
        history_group_layout.addWidget(self.history_table)
        main_layout.addWidget(history_group)

        # --- Bottom Control Buttons ---
        self.time_label = QLabel()
        self.translate_button = QPushButton()
        self.stop_button = QPushButton()
        self.stop_button.setEnabled(False)

        bottom_layout = QHBoxLayout()
        bottom_layout.addWidget(self.time_label)
        bottom_layout.addStretch()
        bottom_layout.addWidget(self.stop_button)
        bottom_layout.addWidget(self.translate_button)
        main_layout.addLayout(bottom_layout)

    def retranslate_ui(self):
        # self.srt_path_button.setText(_("Select SRT File...")) # Button has no text, only icon
        self.history_table.setHorizontalHeaderLabels(
            [_("Status"), _("Source File"), _("Output File"), _("Timestamp"), _("Duration")])
        self.time_label.setText(_("Time: --:--:--"))
        self.translate_button.setText(_("Start Translation"))
        self.stop_button.setText(_("Stop"))
        self.srt_path_label.setText(_("SRT File:"))
        
        # Find the QGroupBox by object name and retranslate its title
        settings_group = self.findChild(QGroupBox, "settings_group_box")
        if settings_group:
            settings_group.setTitle(_("Translation Settings"))
            
        history_group = self.findChild(QGroupBox, "history_group_box")
        if history_group:
            history_group.setTitle(_("History"))
            
        if hasattr(self, 'translation_options'):
            self.translation_options.retranslate_ui()

    def _connect_signals(self):
        self.srt_path_button.clicked.connect(self.select_srt_file)
        self.translate_button.clicked.connect(self.start_translation)
        self.stop_button.clicked.connect(self.stop_translation)
        self.history_table.customContextMenuRequested.connect(self.show_history_context_menu)

    def show_history_context_menu(self, pos):
        row = self.history_table.rowAt(pos.y())
        if row < 0:
            return

        context_menu = QMenu(self)
        
        edit_subtitle_action = context_menu.addAction(_("Edit Subtitles"))
        context_menu.addSeparator()
        open_file_action = context_menu.addAction(_("Open File"))
        open_folder_action = context_menu.addAction(_("Open Containing Folder"))
        
        action = context_menu.exec(self.history_table.mapToGlobal(pos))

        if action == edit_subtitle_action:
            self.edit_history_item_subtitle(row)
        elif action == open_file_action:
            self.open_history_item_file(row)
        elif action == open_folder_action:
            self.open_history_item_folder(row)

    def edit_history_item_subtitle(self, row):
        entry = self.history_data[row]
        # We can edit either the output or the source file. Let's prefer the output file.
        srt_path = entry.get("output_file")
        if not srt_path or srt_path == "N/A" or not os.path.exists(srt_path):
            srt_path = entry.get("source_file")

        if srt_path and os.path.exists(srt_path):
            editor = SubtitleEditorDialog(srt_path, self)
            editor.exec()
        else:
            QMessageBox.warning(self, _("File Not Found"), _("Could not find a valid SRT file to edit."))

    def _open_path(self, path):
        """Cross-platform way to open a file or directory."""
        try:
            if sys.platform == "win32":
                os.startfile(path)
            elif sys.platform == "darwin": # macOS
                subprocess.run(["open", path], check=True)
            else: # linux
                subprocess.run(["xdg-open", path], check=True)
        except (OSError, subprocess.CalledProcessError) as e:
            get_logger(__name__).error(f"Failed to open path {path}: {e}")
            QMessageBox.warning(self, _("Error"), _("Could not open the specified path: {}").format(path))


    def open_history_item_file(self, row):
        # The history data is stored with newest first, so we access it directly by row index
        entry = self.history_data[row]
        file_path = entry.get("output_file")
        if file_path and file_path != "N/A" and os.path.exists(file_path):
            self._open_path(file_path)
        else:
            QMessageBox.warning(self, _("File Not Found"), _("The output file does not exist or is not available."))

    def open_history_item_folder(self, row):
        entry = self.history_data[row]
        file_path = entry.get("output_file")
        if file_path and file_path != "N/A" and os.path.exists(file_path):
            self._open_path(os.path.dirname(file_path))
        else:
            # Fallback to source file's directory if output is not available
            source_path = entry.get("source_file")
            if source_path and os.path.exists(os.path.dirname(source_path)):
                 self._open_path(os.path.dirname(source_path))
            else:
                QMessageBox.warning(self, _("Folder Not Found"), _("The directory could not be found."))

    def select_srt_file(self):
        last_dir = app_config.get("paths.last_srt_dir", os.path.expanduser("~"))
        file_path, _filter = QFileDialog.getOpenFileName(
            self, _("Select SRT File"), last_dir, _("SRT Files (*.srt)"))
        if file_path:
            self.srt_path_edit.setText(file_path)
            app_config.set("paths.last_srt_dir", os.path.dirname(file_path), emit_signal=False)
            app_config.save(emit_signal=False)

    def start_translation(self):
        srt_path = self.srt_path_edit.text()
        if not srt_path:
            QMessageBox.warning(self, _("Warning"), _("Please select an SRT file."))
            return

        options = self.translation_options.get_options()
        options['translator_name'] = options.pop('translator')
        
        if options['translator_name'] == 'OpenAI' and not options.get('model_config'):
            QMessageBox.warning(self, _("Warning"), _("Please select a translation model."))
            return
        
        model_config = options.get('model_config')
        if model_config and (not model_config.get('api_key') or not model_config.get('base_url')):
            provider_name = model_config.get('provider_name', 'Unknown')
            QMessageBox.critical(self, _("Error"), _("API key or Base URL is not configured for provider: {}").format(provider_name))
            return

        self.translate_button.setEnabled(False)
        self.stop_button.setEnabled(True)
        # self.log_table.setRowCount(0) # Obsolete

        # --- Create a dedicated logger for this specific translation task ---
        srt_path = self.srt_path_edit.text()
        video_name = os.path.splitext(os.path.basename(srt_path))[0]
        # Remove existing language code from video name for a cleaner log name
        video_name = re.sub(r'\.([a-z]{2,3}(-[A-Z]{2})?)$', '', video_name)
        work_dir = os.path.dirname(srt_path)
        task_log_path = os.path.join(work_dir, f"{video_name}.log")
        task_logger = create_task_logger(task_log_path)
        task_logger.info(f"--- Starting translation for SRT: {os.path.basename(srt_path)} ---")

        self.worker = TranslationWorker(
            srt_path=srt_path,
            logger=task_logger,
            **options
        )
        self.worker.progress.connect(self.update_status_bar)
        self.worker.time_updated.connect(self._update_timer)
        self.worker.task_finished.connect(self.on_translation_finished)
        self.worker.error.connect(self.on_translation_error)
        self.worker.finished.connect(self.on_worker_finished)
        self.worker.start()

    def stop_translation(self):
        if self.worker and self.worker.isRunning():
            self.worker.stop()

    def update_status_bar(self, message):
        if self.main_window:
            self.main_window.statusBar().showMessage(message)

    def populate_translation_table(self, translation_pairs):
        # This method is now obsolete and will be replaced by history management.
        pass

    def _update_timer(self, elapsed_time=None):
        if self.worker and self.worker.isRunning() and elapsed_time is not None:
            self.time_label.setText(_("Time: {}").format(format_seconds(elapsed_time)))
        else:
            self.time_label.setText(_("Time: --:--:--"))

    def on_translation_finished(self, message, output_path):
        QMessageBox.information(self, _("Success"), _(
            "{}\nOutput file: {}").format(message, output_path))
        # This is now handled in on_worker_finished to get the total time

    def on_translation_error(self, error_message):
        QMessageBox.critical(self, _("Translation Failed"), error_message)
        # This is now handled in on_worker_finished

    def _load_history(self):
        if not os.path.exists(self.history_file):
            self.history_data = []
            return
        try:
            with open(self.history_file, 'r', encoding='utf-8') as f:
                self.history_data = json.load(f)
            
            self.history_table.setRowCount(0)
            for entry in self.history_data:
                self._add_history_row(entry)

        except (json.JSONDecodeError, IOError) as e:
            get_logger(__name__).error(f"Failed to load history file: {e}")
            self.history_data = []
            # Optionally, inform the user
            QMessageBox.warning(self, _("History Error"), _("Could not load translation history file."))

    def _save_history(self):
        try:
            with open(self.history_file, 'w', encoding='utf-8') as f:
                json.dump(self.history_data, f, indent=4, ensure_ascii=False)
        except IOError as e:
            get_logger(__name__).error(f"Failed to save history file: {e}")
            QMessageBox.critical(self, _("History Error"), _("Could not save translation history."))

    def _add_history_entry(self, status, source_file, output_file, duration):
        entry = {
            "status": status,
            "source_file": source_file,
            "output_file": output_file,
            "timestamp": datetime.now().isoformat(),
            "duration": duration
        }
        self.history_data.insert(0, entry) # Add to the beginning of the list
        self._add_history_row(entry, at_top=True)
        self._save_history()

    def _add_history_row(self, entry, at_top=False):
        row_position = 0 if at_top else self.history_table.rowCount()
        if at_top:
            self.history_table.insertRow(row_position)
        else:
            self.history_table.setRowCount(row_position + 1)

        status_item = QTableWidgetItem(entry.get("status", "N/A"))
        # Simple styling for status
        if entry.get("status") == _("Success"):
            status_item.setForeground(Qt.GlobalColor.green)
        elif entry.get("status") == _("Failed"):
            status_item.setForeground(Qt.GlobalColor.red)

        self.history_table.setItem(row_position, 0, status_item)
        self.history_table.setItem(row_position, 1, QTableWidgetItem(entry.get("source_file", "")))
        self.history_table.setItem(row_position, 2, QTableWidgetItem(entry.get("output_file", "")))
        
        timestamp_str = entry.get("timestamp", "")
        if timestamp_str:
            try:
                # Format for display
                dt_object = datetime.fromisoformat(timestamp_str)
                timestamp_str = dt_object.strftime("%Y-%m-%d %H:%M:%S")
            except ValueError:
                pass # Keep original string if parsing fails
        self.history_table.setItem(row_position, 3, QTableWidgetItem(timestamp_str))
        
        duration_str = format_seconds(entry.get("duration", 0))
        self.history_table.setItem(row_position, 4, QTableWidgetItem(duration_str))
        self.history_table.resizeRowsToContents()

    def on_worker_finished(self, success, total_time):
        self.translate_button.setEnabled(True)
        self.stop_button.setEnabled(False)
        self.time_label.setText(
            _("Total Time: {}").format(format_seconds(total_time)))
        
        status = _("Success") if success else _("Failed")
        source_file = self.srt_path_edit.text()
        output_file = self.worker.output_path if success and self.worker else "N/A"
        
        self._add_history_entry(status, source_file, output_file, total_time)
